#ifndef __IOCP_OPERATION_H__
#define __IOCP_OPERATION_H__

#include "DSTHType.h"
#include "AcfDelegate.h"

namespace dsth {

class IOCPOperation : public OVERLAPPED {
public:
    enum {
        kAcceptOperation = 1,
        kReadOperation = 2,
        kWriteOperation = 3
    };
    IOCPOperation(int32_t type) : type_(type) { Reset(); }
    virtual ~IOCPOperation() {}
    void Reset() {
        Internal = 0;
        InternalHigh = 0;
        Offset = 0;
        OffsetHigh = 0;
        hEvent = 0;
        ready_ = 0;
    }
    virtual void Complete(int ec, DWORD bytes_transferred) = 0;
protected:
    long ready_;
    const int32_t type_;
    SOCKET peer_socket_;
    friend class DSTHIocp;
    friend class EventLoop;
private:
    IOCPOperation(const IOCPOperation&);
    void operator=(const IOCPOperation&);
};

class IOCPAcceptOperation : public IOCPOperation {
public:
    typedef Acf::Delegate<void (SOCKET, int)> AcceptHandler;
    IOCPAcceptOperation(const AcceptHandler& handler)
        : IOCPOperation(kAcceptOperation),
        event_handler_(handler) { peer_socket_ = 0; }
    void Complete(int ec, DWORD bytes_transferred) {
        event_handler_(peer_socket_, ec);
    }
private:
    char outbuffer_[1024];
    AcceptHandler event_handler_;
    friend class EventLoop;
};

class IOCPWaiteOperation: public IOCPOperation {
public:
    typedef Acf::Delegate<void (int, DWORD)> WriteHandler;

    IOCPWaiteOperation(SOCKET socket, const WriteHandler& handler)
        : IOCPOperation(kWriteOperation),
        event_handler_(handler) {
        peer_socket_ = socket;
    }
    void Complete(int ec, DWORD bytes_transferred) {
        event_handler_(ec, bytes_transferred);
    }
private:
    WriteHandler event_handler_;
};

} // namespace
#endif // __IOCP_OPERATION_H__
